import {_decorator,systemEvent, Touch, Node,Component, geometry, math, Camera, Material, NodePool, Vec3, v3, EventKeyboard, macro, resources, Toggle, Asset, MeshRenderer, RenderableComponent, Vec2, instantiate, SystemEventType, RenderTexture, Sprite, Texture2D, ImageAsset, view, UITransform, SpriteFrame, color, Color} from 'cc';
import RecastDetourManager from "./recastdetourjs/tool/RecastDetourManager";
import {IObstacle} from "cocos-recast/dist/INavigationEngine";
import {RecastJSPlugin} from "cocos-recast";

const { ccclass, property } = _decorator;

@ccclass('Main')
export class Main extends Component {
    private recastDetourManager!: RecastDetourManager;
    @property(Node)
    roleNode : Node = null!;
    @property(Camera)
    camera : Camera = null!;
    @property(Material)
    debugMaterial : Material = null!;
    @property(Sprite)
    fogWar : Sprite = null!;

    private imageAsset: ImageAsset = null!;
    private texture2d: Texture2D = null!;
    /**存储像素数据的内存块 */
    private buffer: ArrayBuffer = null!;
    /**颜色分量一维数组，供渲染使用 */
    private pixelColor: Uint8Array = null!;
    private width = 960;
    private height = 640;

    async start () {

        var rt = new RenderTexture();
    
        this.recastDetourManager = await RecastDetourManager.getInstanceByNode(this.node,this.debugMaterial,1,this.node);


        this.node.on(Node.EventType.TOUCH_END,this.onTouch,this);

        let id = this.recastDetourManager.addAgents(new Vec3(0, 0, 0));
        let comp = this.roleNode.getComponent(RenderableComponent)!;
        comp.unscheduleAllCallbacks();
        comp.schedule(()=>{
            this.roleNode.setWorldPosition(this.recastDetourManager.crowd!.getAgentPosition(id));
            this.roleNode.position = new Vec3(this.roleNode.position.x, this.roleNode.position.y + 0.5, this.roleNode.position.z);
        });

        // this.initTexture();
        // this.initPixelColor();
    }

    initTexture() {
        // 存储 Uint8Array 数据，存入 imageAsset, 然后通过 texture2D.image = imageAsset创建texture2D, 
        // 之后把texture2d 赋值给Sprite渲染。
        this.imageAsset = new ImageAsset();
        this.imageAsset.reset({
            width : this.width,
            height : this.height,
            close
        });

        this.texture2d = new Texture2D();
        this.texture2d.reset({
            width : this.width,
            height : this.height,
            format : Texture2D.PixelFormat.RGBA8888
        });
        this.texture2d.image = this.imageAsset;
        
        let spf: SpriteFrame = new SpriteFrame();
        spf.texture = this.texture2d;
        this.fogWar.spriteFrame = spf;
    }

    private initPixelColor() {
        this.buffer = new ArrayBuffer(this.width * this.height * 4);
        this.pixelColor = new Uint8Array(this.buffer);
        this.pixelColor.fill(0);
    }

    onTouch(touch : Touch){
        let ray = this.camera.screenPointToRay(touch.getLocationX(), touch.getLocationY());
        let comps = this.node.getComponentsInChildren(MeshRenderer);
        let distance = Number.MAX_VALUE;
        for(let i = 0;i < comps.length;++i){
            let dis = geometry.intersect.rayModel(ray, comps[i].model!,{mode : geometry.ERaycastMode.CLOSEST,doubleSided : false,distance : Number.MAX_SAFE_INTEGER});
            if(dis && dis < distance){
                distance = dis;
            }
        }
        if(distance == Number.MIN_VALUE){
            return;
        }
        let out = v3();
        ray.computeHit(out,distance);

        this.recastDetourManager.agentGoto(out);
    }

    update (deltaTime: number) {
        if(!this.recastDetourManager){
            return;
        }
        this.recastDetourManager.update(deltaTime);
    }

    onDraw()
    {
        this.drawRowPixel(5, 100, 100);
        this.updateFog();
    }
    
    private testColor = Color.GREEN;
    drawRowPixel(startX: number, endX: number, y: number) {
        let index = (y * this.width + startX) * 4;
        for (let x = startX; x <= endX; ++x) {
            this.pixelColor[index] = this.testColor.r;
            this.pixelColor[index + 1] = this.testColor.g;
            this.pixelColor[index + 2] = this.testColor.b;
            this.pixelColor[index + 3] = this.testColor.a;
            index += 4;
        }
    }
    
    updateFog() {
        this.texture2d.uploadData(this.pixelColor);
    }

}
